package logic

import (
	"common/global"
	"common/model"
	"context"
	"errors"
	"fmt"
	"github.com/go-redis/redis/v8"
	"order_server/dao/dao_redis"
	order "order_server/proto"
	"strconv"
	"sync"
)

// OrderUpdatePaid 处理订单支付回调
func (o *OrderServer) OrderUpdatePaid(ctx context.Context, req *order.OrderUpdatePaidRequest) (*order.OrderUpdatePaidResponse, error) {
	fmt.Println("回调", req.Paid, req.OrderId)
	// 开启事务
	err := global.Client.Watch(context.Background(), func(tx *redis.Tx) error {
		// 订单状态修改
		if err := model.OrderUpdatePaid(req.OrderId, req.Paid); err != nil {
			return err
		}
		// 根据订单号查询订单信息
		orderList, err := model.GetOrderIdInfo(req.OrderId)
		if err != nil {
			return err
		}

		// 支付成功时处理库存
		if req.Paid == 1 {
			// 检查是否为秒杀订单
			if orderList.OrderType == 2 { // 秒杀订单
				// 查询秒杀订单详情
				seckillOrder, err := model.GetSeckillOrderByOrderId(orderList.Id)
				if err != nil {
					return err
				}
				// 扣减秒杀活动的MySQL库存
				if err = model.SeckillStockDel(seckillOrder.ActivityId, orderList.Quantity); err != nil {
					return err
				}
			} else {
				// 普通订单处理
				// 根据订单 ID 查询订单购物详情
				info, err := model.GetOrderCatInfo(orderList.Id)
				if err != nil {
					return err
				}
				if info.ProductId != 0 {
					// 商品库存扣减(单条商品)
					if err = model.ProductStockDel(info.ProductId, orderList.Quantity); err != nil {
						return err
					}
					// 购物车缓存扣减
					if err = dao_redis.CarProductDel(orderList.UserId, info.ProductId); err != nil {
						return err
					}
				} else {
					// 查询购物车商品 key
					productIds, err := dao_redis.GetCarList(orderList.UserId)
					if err != nil {
						return err
					}
					// 并发处理商品库存扣减
					var (
						productIdsInt []int
						stocks        []int
					)
					var wg sync.WaitGroup
					errChan := make(chan error, len(productIds))
					for _, s := range productIds {
						id, err := strconv.Atoi(s)
						if err != nil {
							return err
						}
						productIdsInt = append(productIdsInt, id)

						wg.Add(1)
						go func(id int) {
							defer wg.Done()
							catMap, err := global.Client.HGetAll(context.Background(), s).Result()
							if err != nil {
								errChan <- err
								return
							}
							stock, err := strconv.Atoi(catMap["Stock"])
							if err != nil {
								errChan <- err
								return
							}
							stocks = append(stocks, stock)
						}(id)
					}
					// 等待所有 goroutine 完成
					wg.Wait()
					close(errChan)
					// 检查是否有错误
					for err = range errChan {
						if err != nil {
							return err
						}
					}
					// 批量商品库存扣减
					for i, id := range productIdsInt {
						if err = model.ProductStockDel(int64(id), int64(stocks[i])); err != nil {
							return err
						}
					}
					// 购物车清空
					if err = dao_redis.CarDel(orderList.UserId); err != nil {
						return err
					}
				}
			}
		}
		return nil
	})
	if err != nil {
		return nil, errors.New("redis事务启动失败")
	}

	fmt.Println("回调", req.Paid, req.OrderId)
	return &order.OrderUpdatePaidResponse{}, nil
}
